from flask import Flask, render_template, jsonify, request, redirect, url_for, session, flash
from pyhive import hive
import traceback
from datetime import datetime, timedelta
import threading
import time
from auth_manager import AuthManager
from functools import wraps

app = Flask(__name__)
app.secret_key = 'your-secret-key-here'  # 用于session加密

auth_manager = AuthManager()

# 设置session的配置
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)  # session有效期7天
app.config['SESSION_COOKIE_SECURE'] = False  # 如果不使用HTTPS，设置为False
app.config['SESSION_COOKIE_HTTPONLY'] = True  # 防止JavaScript访问cookies


def get_hive_connection():
    """获取 Hive 连接"""
    try:
        print("尝试连接 Hive...")
        conn = hive.Connection(
            host='192.168.88.161',
            port=10000,
            database='weather_db',
            auth='NOSASL'
        )
        print("Hive 连接成功！")
        return conn
    except Exception as e:
        print(f"Hive 连接失败: {str(e)}")
        print(traceback.format_exc())
        return None


# 全局缓存
cache = {
    'weather_data': None,
    'daily_stats': None,
    'last_update': None
}


def update_cache():
    """后台更新缓存数据"""
    while True:
        try:
            print("\n=== 更新缓存数据 ===")
            conn = get_hive_connection()
            if conn:
                cursor = conn.cursor()

                # 获取天气数据
                weather_query = """
                SELECT *
                FROM weather_data
                ORDER BY date_time DESC
                LIMIT 100
                """
                cursor.execute(weather_query)
                weather_data = cursor.fetchall()

                # 获取天气数据列名
                cursor.execute("DESCRIBE weather_data")
                weather_columns = [col[0] for col in cursor.fetchall()]

                # 获取每日统计数据
                daily_query = """
                SELECT *
                FROM daily_weather_stats
                ORDER BY dt DESC
                LIMIT 30
                """
                cursor.execute(daily_query)
                daily_data = cursor.fetchall()

                # 获取每日统计数据列名
                cursor.execute("DESCRIBE daily_weather_stats")
                daily_columns = [col[0] for col in cursor.fetchall()]

                # 转换天气数据
                formatted_weather = []
                for row in weather_data:
                    item = dict(zip(weather_columns, row))
                    if item['date_time']:
                        item['date_time'] = str(item['date_time'])
                    for key in ['temperature', 'humidity', 'wind_speed', 'precipitation']:
                        if item.get(key) is not None:
                            item[key] = float(item[key])
                    formatted_weather.append(item)

                # 转换每日统计数据
                formatted_daily = []
                for row in daily_data:
                    item = dict(zip(daily_columns, row))
                    if item.get('dt'):
                        item['dt'] = str(item['dt'])
                    for key in ['max_temp', 'min_temp', 'avg_temp', 'avg_humidity', 'total_precipitation']:
                        if item.get(key) is not None:
                            item[key] = float(item[key])
                    formatted_daily.append(item)

                # 更新缓存
                cache['weather_data'] = formatted_weather
                cache['daily_stats'] = formatted_daily
                cache['last_update'] = datetime.now()

                cursor.close()
                conn.close()
                print(f"缓存更新成功，天气数据: {len(formatted_weather)}条，每日统计: {len(formatted_daily)}条")

        except Exception as e:
            print(f"缓存更新失败: {str(e)}")
            print(traceback.format_exc())

        # 每5分钟更新一次
        time.sleep(300)


# 启动后台更新线程
update_thread = threading.Thread(target=update_cache, daemon=True)
update_thread.start()


def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if 'username' not in session:
            print("login_required: 未检测到session，重定向到登录页面")  # 调试信息
            return redirect(url_for('login'))
        return f(*args, **kwargs)

    return decorated_function


@app.route('/')
def index():
    print("访问首页，当前session:", dict(session))
    return render_template('index.html')


@app.route('/login', methods=['GET', 'POST'])
def login():
    try:
        print("当前session状态:", dict(session))

        if request.method == 'POST':
            username = request.form.get('username')
            password = request.form.get('password')

            print(f"登录尝试: username={username}")

            user = auth_manager.verify_user(username, password)
            if user:
                session['username'] = user['username']
                session.permanent = True
                print("登录成功，设置session:", dict(session))
                return redirect(url_for('dashboard'))
            else:
                print("登录失败，用户验证未通过")
                flash('用户名或密码错误', 'error')
                return render_template('login.html')

    except Exception as e:
        print(f"登录过程出错: {str(e)}")
        print(traceback.format_exc())
        flash('登录时发生错误，请稍后重试', 'error')
        return render_template('login.html')

    # GET请求，显示登录页面
    return render_template('login.html')


@app.route('/register', methods=['GET', 'POST'])
def register():

    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')

        if not username or not password:
            flash('请填写所有必填字段', 'error')
            return render_template('register.html')

        try:
            if auth_manager.create_user(username, password):
                flash('注册成功！请登录', 'success')
                return redirect(url_for('login'))
            else:
                flash('注册失败，用户名可能已存在', 'error')
                return render_template('register.html')

        except Exception as e:
            flash('注册时发生错误，请稍后重试', 'error')
            print(f"注册错误: {str(e)}")
            return render_template('register.html')

    return render_template('register.html')


@app.route('/logout')
def logout():
    session.clear()
    print("用户已登出，session已清除")
    return redirect(url_for('login'))


@app.route('/dashboard')
@login_required
def dashboard():
    if 'username' not in session:
        return redirect(url_for('login'))
    return render_template('dashboard.html', username=session.get('username'))


@app.route('/api/weather/current')
def get_current_weather():
    try:
        if cache['weather_data'] is not None and cache['last_update'] is not None:
            age = datetime.now() - cache['last_update']
            if age.total_seconds() < 300:  # 5分钟
                return jsonify({
                    'status': 'success',
                    'data': cache['weather_data'],
                    'cached': True,
                    'cache_age': int(age.total_seconds())
                })

        return jsonify({
            'status': 'error',
            'message': '数据正在加载中，请稍后再试'
        })

    except Exception as e:
        print("\n错误详情:", str(e))
        print("详细跟踪:", traceback.format_exc())
        return jsonify({
            'status': 'error',
            'message': str(e)
        }), 500


@app.route('/api/weather/stats/daily')
def get_daily_stats():
    try:
        if cache['daily_stats'] is not None and cache['last_update'] is not None:
            age = datetime.now() - cache['last_update']
            if age.total_seconds() < 300:  # 5分钟
                return jsonify({
                    'status': 'success',
                    'data': cache['daily_stats'],
                    'cached': True,
                    'cache_age': int(age.total_seconds())
                })

        return jsonify({
            'status': 'error',
            'message': '数据正在加载中，请稍后再试'
        })

    except Exception as e:
        print("\n错误详情:", str(e))
        print("详细跟踪:", traceback.format_exc())
        return jsonify({
            'status': 'error',
            'message': str(e)
        }), 500


def get_life_index():
    """获取生活指数数据"""
    # 这里可以调用天气 API 获取实际数据，这里使用模拟数据作为示例
    life_indices = {
        'comfort': {
            'name': '舒适度指数',
            'level': '舒适',
            'description': '白天温度适中，风力适宜，相对湿度偏低，天气舒适。'
        },
        'dressing': {
            'name': '穿衣指数',
            'level': '较舒适',
            'description': '建议着长袖T恤、衬衫加单裤等服装。年老体弱者宜着长袖衬衫、单裤、薄套装。'
        },
        'uv': {
            'name': 'UV指数',
            'level': '中等',
            'description': '涂擦SPF大于15、PA+防晒护肤品。'
        },
        'sport': {
            'name': '运动指数',
            'level': '适宜',
            'description': '天气较好，适宜户外运动。'
        },
        'car_washing': {
            'name': '洗车指数',
            'level': '较适宜',
            'description': '较适宜洗车，未来一天无雨，风力较小，擦洗一新的汽车至少能保持一天。'
        },
        'travel': {
            'name': '旅游指数',
            'level': '适宜',
            'description': '天气较好，温度适宜，是个好天气哦。'
        }
    }
    return life_indices


@app.route('/life_indices')
def life_indices():
    indices = get_life_index()
    return render_template('life_indices.html', indices=indices)


if __name__ == '__main__':
    print("启动 Flask 应用...")
    print("访问地址: http://localhost:5000")
    app.run(debug=True, host='127.0.0.1', port=5000)